'''
Created on May 9, 2011

@author: peterd
'''

from operator import itemgetter

from mhd.models import MHD_Stop
from web.service.GeoCodingBroker import GeoCodingBroker
from web.service.DirectionBroker import DirectionBroker
from infra.util.geoutil import getBoundingBox, getDistanceOnUnitSphere, LatLng
from geo.Radius import Radius
from mhd.conf import num_direction_retries

# TODO: move to mhd.exceptions
class MHD_NoStopFound:
    pass

class InvalidLatLng:
    pass



class MHD_StopLocator:
    
    def find_nearby_stops(self, street, streetNum, city = u'Bratislava'):
        geoCodingBroker = GeoCodingBroker()
        (lat, lng, acuracy) = geoCodingBroker.geoCode(street, streetNum, city)
        return self.find_nearby_stops_by_latlng__(lat, lng)

        
    def find_nearby_stops_by_latlng(self, lat, lng, radius_dist = 500, radius_unit = 'm'):    
        if lat == 0.0 or lng == 0.0:
            raise InvalidLatLng
            
        return self.find_nearby_stops_by_latlng__(lat, lng, radius_dist, radius_unit)
        

    def find_nearby_stops_by_latlng__(self, lat, lng, radius_dist = 500, radius_unit = 'm'):
        mhd_stops_dist = {}
        
        try:            
            boundingBox = getBoundingBox(lat, lng, Radius(radius_dist, radius_unit))
            mhd_stops = MHD_Stop.objects.filter(lat__gte = boundingBox.north()).filter(lat__lte = boundingBox.south()).filter(lng__gte = boundingBox.west()).filter(lng__lte = boundingBox.east())
            mhd_stops_dist = {}
            for mhd_stop in mhd_stops:
                mhd_stops_dist[mhd_stop] = getDistanceOnUnitSphere(lat, lng, mhd_stop.lat, mhd_stop.lng, 'm')
        except Exception:
            pass     
    
        return sorted(mhd_stops_dist.items(), key=itemgetter(1))